package main

import (
	"context"
	"encoding/json"
	"net/http"

	"github.com/go-kit/kit/endpoint"
)

////////////////////////////////////////////////////////////////////
/////////////// Request & Response

type request struct {
	S string `json:"s"`
}

type response struct {
	S   string `json:"s"`
	Err string `json:"err,omitempty"`
}

////////////////////////////////////////////////////////////////////
/////////////// Decode & Encode

func decodeRequest(ctx context.Context, r *http.Request) (interface{}, error) {
	req := request{}
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		return nil, err
	}
	return req, nil
}

func encodeResponse(ctx context.Context, w http.ResponseWriter, response interface{}) error {
	return json.NewEncoder(w).Encode(response)
}

////////////////////////////////////////////////////////////////////
/////////////// Endpoint

// An endpoint represents a single RPC

func makeUppercaseEndpoint(svc StringService) endpoint.Endpoint {
	return func(ctx context.Context, r interface{}) (interface{}, error) {
		req := r.(request)
		s, err := svc.Uppercase(ctx, req.S)
		if err != nil {
			return response{s, err.Error()}, nil
		}
		return response{s, ""}, nil
	}
}

func makeLowercaseEndpoint(svc StringService) endpoint.Endpoint {
	return func(ctx context.Context, r interface{}) (interface{}, error) {
		req := r.(request)
		s, err := svc.Lowercase(ctx, req.S)
		if err != nil {
			return response{s, err.Error()}, nil
		}
		return response{s, ""}, nil
	}
}
